package com.cloud.bssp.reference;

import java.lang.ref.PhantomReference;
import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
import java.util.ArrayList;
import java.util.List;

/**
 * @description： 虚引用
 * 虚引用也称为“幽灵引用”或者“幻影引用”，它是最弱的一种引用关系。一个对象是否有虚引用的
 * 存在，完全不会对其生存时间构成影响，也无法通过虚引用来取得一个对象实例。为一个对象设置虚
 * 引用关联的唯一目的只是为了能在这个对象被收集器回收时收到一个系统通知。在JDK 1.2版之后提供
 * 了PhantomReference类来实现虚引用
 * <p>
 * 虚幻似鬼魅
 * 队列来帮忙
 * 身形缥缈何处觅
 * 生死此中藏
 * <p>
 * 应用：在jvm中，用来管理直接内存（例如NIO中ByteBuffer申请直接内存allocateDirect）的回收.会将虚引用的回收时间添加到一个队列中。
 * @author：weirx
 * @date：2021/5/19 17:09
 * @version：3.0
 */
public class PhantomReferenceTest {

    static class M {
        int a = 0;
    }

    static ReferenceQueue referenceQueue = new ReferenceQueue();

    public static void main(String[] args) {
        PhantomReference phantomReference = new PhantomReference(new M(), referenceQueue);

        //通过get页不能获取到
        System.out.println(phantomReference.get());

        List list = new ArrayList();
        //模拟线程，不断增加堆空间占用
        new Thread(() -> {
            while (true) {
                list.add(new byte[1024 * 1024]);
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(phantomReference.get());
            }
        }).start();

        //模拟垃圾回收线程，可用于做善后处理，比如nio的直接内存
        new Thread(() -> {
            while (true) {
                //当虚引用对象被回收时，会在队列里面增加一个信息，当我们获取到信息就可以对这个引用做善后处理
                Reference poll = referenceQueue.poll();
                if (poll != null) {
                    System.out.println("虚引用对象被jvm回收了," + poll);
                }
            }
        }).start();
    }
}
